package com.hejie.videoservice.service.impl;

import com.hejie.videoservice.service.VideoProcessingService;
import net.bramp.ffmpeg.FFmpeg;
import net.bramp.ffmpeg.FFmpegExecutor;
import net.bramp.ffmpeg.FFprobe;
import net.bramp.ffmpeg.builder.FFmpegBuilder;
import net.bramp.ffmpeg.probe.FFmpegProbeResult;
import net.bramp.ffmpeg.probe.FFmpegStream;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@Service
public class VideoProcessingServiceImpl implements VideoProcessingService {

    private final FFmpeg ffmpeg;
    private final FFprobe ffprobe;

    public VideoProcessingServiceImpl() throws IOException {
        // 实际生产环境中应通过配置文件指定FFmpeg路径
        this.ffmpeg = new FFmpeg(ResourceUtils.getFile("classpath:ffmpeg").getAbsolutePath());
        this.ffprobe = new FFprobe(ResourceUtils.getFile("classpath:ffprobe").getAbsolutePath());
    }

    @Override
    public boolean generateThumbnail(String videoPath, String outputPath, int timeInSeconds) {
        try {
            FFmpegProbeResult probeResult = ffprobe.probe(videoPath);
            long durationSeconds = Math.round(probeResult.getFormat().duration);

            // 如果请求的时间超过视频时长，使用视频中间点
            if (timeInSeconds > durationSeconds) {
                timeInSeconds = (int) (durationSeconds / 2);
            }

            FFmpegBuilder builder = new FFmpegBuilder()
                    .setInput(videoPath)
                    .overrideOutputFiles(true)
                    .addOutput(outputPath)
                    .setVideoFrameRate(24, 1)
                    .setVideoFilter("scale=640:-1")
                    .setDuration(1)
                    .setStartTime(timeInSeconds)
                    .done();

            FFmpegExecutor executor = new FFmpegExecutor(ffmpeg, ffprobe);
            executor.createJob(builder).run();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public Map<String, Object> getVideoMetadata(String videoPath) {
        Map<String, Object> metadata = new HashMap<>();
        try {
            FFmpegProbeResult probeResult = ffprobe.probe(videoPath);
            metadata.put("duration", probeResult.getFormat().duration);
            metadata.put("size", probeResult.getFormat().size);
            metadata.put("bit_rate", probeResult.getFormat().bit_rate);
            metadata.put("format_name", probeResult.getFormat().format_name);

            // 获取视频流信息
            for (FFmpegStream stream : probeResult.getStreams()) {
                if (stream.isVideo()) {
                    metadata.put("video_codec", stream.codec_name);
                    metadata.put("width", stream.width);
                    metadata.put("height", stream.height);
                    metadata.put("frame_rate", stream.avg_frame_rate);
                } else if (stream.isAudio()) {
                    metadata.put("audio_codec", stream.codec_name);
                    metadata.put("sample_rate", stream.sample_rate);
                    metadata.put("channels", stream.channels);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return metadata;
    }

    @Override
    public File transcodeVideo(String inputPath, String outputPath, String format) {
        try {
            FFmpegBuilder builder = new FFmpegBuilder()
                    .setInput(inputPath)
                    .overrideOutputFiles(true)
                    .addOutput(outputPath)
                    .setFormat(format)
                    .disableSubtitle()
                    .done();

            FFmpegExecutor executor = new FFmpegExecutor(ffmpeg, ffprobe);
            executor.createJob(builder).run();
            return new File(outputPath);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public Map<String, File> generateMultiResolutionVersions(String inputPath, String outputDir, String[] resolutions) {
        Map<String, File> result = new HashMap<>();
        File outputDirectory = new File(outputDir);
        if (!outputDirectory.exists()) {
            outputDirectory.mkdirs();
        }

        try {
            String baseFileName = new File(inputPath).getName().split("\\.")[0];

            for (String resolution : resolutions) {
                String[] dimensions = resolution.split("p");
                int width = Integer.parseInt(dimensions[0]);
                String outputPath = outputDir + File.separator + baseFileName + "_" + resolution + ".mp4";

                FFmpegBuilder builder = new FFmpegBuilder()
                        .setInput(inputPath)
                        .overrideOutputFiles(true)
                        .addOutput(outputPath)
                        .setVideoFilter("scale=" + width + ":-1")
                        .setVideoCodec("libx264")
                        .setAudioCodec("aac")
                        .setFormat("mp4")
                        .done();

                FFmpegExecutor executor = new FFmpegExecutor(ffmpeg, ffprobe);
                executor.createJob(builder).run();
                result.put(resolution, new File(outputPath));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}